﻿using System;
using System.Collections.Generic;
using ELab.Exceptions;
using ELab.Settings;
using ELab.Threading;
using ELab.Core.Serialization.Data;

namespace ELab.Organization
{
    /// <summary>
    /// All Client applications that can send/receive messages to/from this ELab server are stored in this class.
    /// </summary>
    public class ELabClientApplicationList : IRunnable
    {
        #region Public properties

        /// <summary>
        /// A collection that stores client applications.
        /// ELabClientApplication objects count is equals to total application definition in Settings file.
        /// </summary>
        public SortedList<string, ELabClientApplication> Applications { get; private set; }

        /// <summary>
        /// Reference to settings.
        /// </summary>
        private readonly ELabSettings _settings;

        #endregion

        #region Constrcutors

        /// <summary>
        /// Contructor. Gets applications from given settings file.
        /// </summary>
        public ELabClientApplicationList()
        {
            _settings = ELabSettings.Instance;
            Applications = new SortedList<string, ELabClientApplication>();
            try
            {
                RefreshApplicationList();
            }
            catch (ELabException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new ELabException("Can not read settings file.", ex);
            }
        }

        #endregion

        #region Public methods

        public void Start()
        {
            foreach (var application in Applications.Values)
            {
                application.Start();
            }
        }

        public void Stop(bool waitToStop)
        {
            foreach (var application in Applications.Values)
            {
                application.Stop(waitToStop);
            }
        }

        public void WaitToStop()
        {
            foreach (var application in Applications.Values)
            {
                application.WaitToStop();
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Reads the xml file and creates client applications using _settings.
        /// </summary>
        public void RefreshApplicationList()
        {
            var users = ProviderFactory.UserProvider.Users;
            if (users != null)
            {
                foreach (var application in users)
                {
                    if (!Applications.ContainsKey(application.ApplicationName))
                    {
                        //Create application object
                        var clientApplication = new ELabClientApplication(application.UserName);

                        //Add new application to list
                        Applications.Add(clientApplication.Name, clientApplication);
                        clientApplication.Start();
                    }
                }
            }

            //// Old code - Use Application from Setting files
            //foreach (var application in _settings.Applications)
            //{
            //    //Create application object
            //    var clientApplication = new ELabClientApplication(application.Name);

            //    //Add new application to list
            //    Applications.Add(clientApplication.Name, clientApplication);
            //}
        }

        #endregion
    }
}
